package client

import (
	"context"
	equipment "equipment_server/proto"
	"fmt"
	pool "github.com/processout/grpc-go-pool"
	"google.golang.org/grpc"
	"sync"
	"time"
)

var (
	grpcPool *pool.Pool
	poolOnce sync.Once
)

// 初始化gRPC连接池，只执行一次
func InitGRPCPool() {
	poolOnce.Do(func() {
		factory := func() (*grpc.ClientConn, error) {
			return grpc.Dial(fmt.Sprintf("%s:%d", "127.0.0.1", 9992), grpc.WithInsecure())
		}
		p, err := pool.New(factory, 5, 500, time.Minute)
		if err != nil {
			panic(err)
		}
		grpcPool = p
	})
}

type EquipmentHandler func(ctx context.Context, client equipment.EquipmentClient) (interface{}, error)

func EquipmentClient(ctx context.Context, handler EquipmentHandler) (interface{}, error) {
	InitGRPCPool() // 确保连接池已初始化
	conn, err := grpcPool.Get(ctx)
	if err != nil {
		return nil, err
	}
	defer conn.Close() // 用完归还
	client := equipment.NewEquipmentClient(conn)
	return handler(ctx, client)
}
func GetPdf(ctx context.Context, in *equipment.GetPdfRequest) (*equipment.GetPdfResponse, error) {
	client, err := EquipmentClient(ctx, func(ctx context.Context, client equipment.EquipmentClient) (interface{}, error) {
		pdf, err := client.GetPdf(ctx, in)
		if err != nil {
			return nil, err
		}
		return pdf, nil
	})
	if err != nil {
		return nil, err
	}
	return client.(*equipment.GetPdfResponse), nil
}
func BindDevice(ctx context.Context, in *equipment.BindDeviceRequest) (*equipment.BindDeviceResponse, error) {
	client, err := EquipmentClient(ctx, func(ctx context.Context, client equipment.EquipmentClient) (interface{}, error) {
		pdf, err := client.BindDevice(ctx, in)
		if err != nil {
			return nil, err
		}
		return pdf, nil
	})
	if err != nil {
		return nil, err
	}
	return client.(*equipment.BindDeviceResponse), nil
}
func UnbindDevice(ctx context.Context, in *equipment.UnbindDeviceRequest) (*equipment.UnbindDeviceResponse, error) {
	client, err := EquipmentClient(ctx, func(ctx context.Context, client equipment.EquipmentClient) (interface{}, error) {
		pdf, err := client.UnbindDevice(ctx, in)
		if err != nil {
			return nil, err
		}
		return pdf, nil
	})
	if err != nil {
		return nil, err
	}
	return client.(*equipment.UnbindDeviceResponse), nil
}
func ObtainHealthData(ctx context.Context, in *equipment.ObtainHealthDataRequest) (*equipment.ObtainHealthDataResponse, error) {
	client, err := EquipmentClient(ctx, func(ctx context.Context, client equipment.EquipmentClient) (interface{}, error) {
		pdf, err := client.ObtainHealthData(ctx, in)
		if err != nil {
			return nil, err
		}
		return pdf, nil
	})
	if err != nil {
		return nil, err
	}
	return client.(*equipment.ObtainHealthDataResponse), nil
}
